package cn.lijiajia3515.cairo.auth.modules.resource;

import cn.lijiajia3515.cairo.core.exception.UnknownBusinessException;
import cn.lijiajia3515.cairo.security.context.CairoSecurityContextHolder;
import cn.lijiajia3515.cairo.security.oauth2.jwt.CairoJwtPrincipal;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.security.oauth2.jwt.Jwt;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PatchMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;
import java.util.Optional;

/**
 * Resource Api
 */
@RequestMapping("/api/resource")
@RestController
public class ResourceApi {

	private final ResourceService resourceService;

	public ResourceApi(ResourceService resourceService) {
		this.resourceService = resourceService;
	}

	@GetMapping("/my")
	@PreAuthorize("hasAnyAuthority('account')")
	public List<ResourceTreeNode> my(@AuthenticationPrincipal CairoJwtPrincipal principal) {
		return resourceService.treeFindByUid(principal.getAppId(), CairoSecurityContextHolder.authenticationAccountId());
	}

	//Operate
	@PostMapping("/save")
	@PreAuthorize("hasAnyAuthority('scp_save:resource')")
	public ResourceTreeNode save(@AuthenticationPrincipal CairoJwtPrincipal principal, @RequestBody SaveResourceParam param) {
		return resourceService.save(principal.getAppId(), param);
	}

	@PutMapping("/modify")
	@PreAuthorize("hasAnyAuthority('scp_modify:resource')")
	public Optional<ResourceTreeNode> modify(@AuthenticationPrincipal CairoJwtPrincipal principal, @RequestBody ModifyResourceParam param) {
		return resourceService.modify(principal.getAppId(), param);
	}

	@PatchMapping("/move")
	@PreAuthorize("hasAnyAuthority('scp_modify:resource')")
	public void move(@AuthenticationPrincipal CairoJwtPrincipal principal, @RequestBody MoveResourceParam param) {
		resourceService.move(principal.getAppId(), param);
	}

	@DeleteMapping("/delete")
	@PreAuthorize("hasAnyAuthority('scp_delete:resource')")
	public List<ResourceTreeNode> delete(@AuthenticationPrincipal CairoJwtPrincipal principal, @RequestBody DeleteResourceParam param) {

		return resourceService.delete(principal.getAppId(), param);
	}

	//find
	@PostMapping("/find")
	@PreAuthorize("hasAnyAuthority('scp_find:resource')")
	public List<ResourceTreeNode> find(@AuthenticationPrincipal CairoJwtPrincipal principal, FindResourceParam param) {
		return resourceService.find(principal.getAppId(), param);
	}

	@PostMapping("/find_tree")
	@PreAuthorize("hasAnyAuthority('scp_find:resource')")
	public List<ResourceTreeNode> tree(@AuthenticationPrincipal CairoJwtPrincipal principal) {
		return resourceService.findTree(principal.getAppId());
	}

	@GetMapping("/find_id/{id}")
	@PreAuthorize("hasAnyAuthority('scp_find:resource')")
	public ResourceTreeNode find(@AuthenticationPrincipal CairoJwtPrincipal principal, @PathVariable String id) {
		return resourceService.treeFindById(principal.getAppId(), id).orElseThrow(() -> new UnknownBusinessException("111"));
	}


}
